//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.tl.satoken.service;

import com.tl.satoken.domain.entity.MBTISquare;
import com.tl.satoken.domain.entity.Player;
import com.tl.satoken.domain.entity.Position;
import com.tl.satoken.domain.entity.RoomInfo;
import com.tl.satoken.domain.entity.RoomJoinResult;
import jakarta.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class RoomService {
    private static final Logger log = LoggerFactory.getLogger(RoomService.class);
    private static final int MAX_PLAYERS_PER_ROOM = 2;
    private static final int GRID_WIDTH = 10;
    private static final int GRID_HEIGHT = 10;
    private static final String ROOM_PREFIX = "game:room:";
    private static final String PLAYER_PREFIX = "game:player:";
    private static final String ROOM_COUNTER = "game:room:counter";
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public RoomService() {
    }

    @PostConstruct
    public void init() {
        this.cleanupOldData();
    }

    private void cleanupOldData() {
        try {
            log.info("清理旧的游戏数据...");
            Set<String> keys = this.redisTemplate.keys("game:*");
            if (keys != null && !keys.isEmpty()) {
                this.redisTemplate.delete(keys);
                log.info("清理了 {} 个旧的游戏数据", keys.size());
            }
        } catch (Exception e) {
            log.warn("清理旧数据时出现异常: {}", e.getMessage());
        }

    }

    public RoomJoinResult joinRoom(Player player) {
        log.info("玩家 {} 尝试加入房间，MBTI类型: {}", player.getUsername(), player.getMbtiType());

        try {
            String playerKey = "game:player:" + player.getId();
            if (Boolean.TRUE.equals(this.redisTemplate.hasKey(playerKey))) {
                return new RoomJoinResult(false, "玩家已在房间中", (String)null);
            } else if (player.getMbtiType() == null) {
                return new RoomJoinResult(false, "请先设置MBTI人格类型", (String)null);
            } else {
                String targetRoomId = this.findAvailableRoom(player.getMbtiType());
                if (targetRoomId == null) {
                    targetRoomId = this.createNewRoom(player.getMbtiType());
                    log.info("为MBTI广场 {} 创建新房间: {}", player.getMbtiType(), targetRoomId);
                }

                String roomKey = "game:room:" + targetRoomId;
                Long roomSize = this.redisTemplate.opsForSet().size(roomKey);
                if (roomSize != null && roomSize >= 2L) {
                    return new RoomJoinResult(false, "房间已满", (String)null);
                } else {
                    Position startPos = this.generateRandomFreePosition(targetRoomId);
                    player.setPosition(startPos);
                    player.setRoomId(targetRoomId);
                    player.setStatus("online");
                    this.redisTemplate.opsForSet().add(roomKey, new Object[]{player});
                    this.redisTemplate.opsForValue().set(playerKey, targetRoomId, 30L, TimeUnit.MINUTES);
                    log.info("玩家 {} 成功加入房间 {}, 当前房间人数: {}", new Object[]{player.getUsername(), targetRoomId, this.getRoomPlayerCount(targetRoomId)});
                    return new RoomJoinResult(true, "加入成功", targetRoomId);
                }
            }
        } catch (Exception e) {
            log.error("加入房间时出现异常: {}", e.getMessage(), e);
            return new RoomJoinResult(false, "加入房间失败: " + e.getMessage(), (String)null);
        }
    }

    public boolean leaveRoom(String playerId) {
        try {
            String playerKey = "game:player:" + playerId;
            String roomId = (String)this.redisTemplate.opsForValue().get(playerKey);
            if (roomId == null) {
                return false;
            } else {
                String roomKey = "game:room:" + roomId;
                Set<Object> players = this.redisTemplate.opsForSet().members(roomKey);
                if (players != null) {
                    players.removeIf((p) -> p instanceof Player ? ((Player)p).getId().equals(playerId) : false);
                    this.redisTemplate.delete(roomKey);
                    if (!players.isEmpty()) {
                        this.redisTemplate.opsForSet().add(roomKey, players.toArray());
                    }
                }

                this.redisTemplate.delete(playerKey);
                log.info("玩家 {} 离开房间 {}, 剩余人数: {}", new Object[]{playerId, roomId, this.getRoomPlayerCount(roomId)});
                if (this.getRoomPlayerCount(roomId) == 0) {
                    this.redisTemplate.delete(roomKey);
                    log.info("房间 {} 已清空，删除房间", roomId);
                }

                return true;
            }
        } catch (Exception e) {
            log.error("离开房间时出现异常: {}", e.getMessage(), e);
            return false;
        }
    }

    public List<Player> getPlayersInRoom(String roomId) {
        try {
            String roomKey = "game:room:" + roomId;
            Set<Object> players = this.redisTemplate.opsForSet().members(roomKey);
            if (players == null) {
                return new ArrayList();
            } else {
                List<Player> playerList = new ArrayList();

                for(Object obj : players) {
                    if (obj instanceof Player) {
                        playerList.add((Player)obj);
                    }
                }

                return playerList;
            }
        } catch (Exception e) {
            log.error("获取房间玩家时出现异常: {}", e.getMessage(), e);
            return new ArrayList();
        }
    }

    public int getRoomPlayerCount(String roomId) {
        try {
            String roomKey = "game:room:" + roomId;
            Long size = this.redisTemplate.opsForSet().size(roomKey);
            return size != null ? size.intValue() : 0;
        } catch (Exception e) {
            log.error("获取房间人数时出现异常: {}", e.getMessage(), e);
            return 0;
        }
    }

    public List<RoomInfo> getAllRooms() {
        try {
            List<RoomInfo> roomInfos = new ArrayList();
            Set<String> keys = this.redisTemplate.keys("game:room:*");
            if (keys != null) {
                for(String key : keys) {
                    if (!key.contains(":mbti") && !key.endsWith(":counter")) {
                        String roomId = key.substring("game:room:".length());
                        if (!"counter".equals(roomId)) {
                            RoomInfo roomInfo = this.getRoomInfo(roomId);
                            if (roomInfo != null) {
                                roomInfos.add(roomInfo);
                            }
                        }
                    }
                }
            }

            return roomInfos;
        } catch (Exception e) {
            log.error("获取所有房间时出现异常: {}", e.getMessage(), e);
            return new ArrayList();
        }
    }

    public RoomInfo getRoomInfo(String roomId) {
        try {
            int playerCount = this.getRoomPlayerCount(roomId);
            if (playerCount < 0) {
                return null;
            } else {
                String roomMbtiKey = "game:room:" + roomId + ":mbti";
                String mbtiTypeName = (String)this.redisTemplate.opsForValue().get(roomMbtiKey);
                MBTISquare mbtiSquare = null;
                if (mbtiTypeName != null) {
                    mbtiSquare = MBTISquare.fromString(mbtiTypeName);
                } else {
                    for(MBTISquare type : MBTISquare.values()) {
                        if (roomId.startsWith(type.name() + "_")) {
                            mbtiSquare = type;
                            break;
                        }
                    }
                }

                return new RoomInfo(roomId, playerCount, 2, mbtiSquare);
            }
        } catch (Exception e) {
            log.error("获取房间信息时出现异常: {}", e.getMessage(), e);
            return null;
        }
    }

    public boolean updatePlayerPosition(String playerId, Player updatedPlayer) {
        try {
            String playerKey = "game:player:" + playerId;
            String roomId = (String)this.redisTemplate.opsForValue().get(playerKey);
            if (roomId == null) {
                return false;
            } else {
                String roomKey = "game:room:" + roomId;
                Set<Object> players = this.redisTemplate.opsForSet().members(roomKey);
                if (players != null) {
                    players.removeIf((p) -> p instanceof Player ? ((Player)p).getId().equals(playerId) : false);
                    players.add(updatedPlayer);
                    this.redisTemplate.delete(roomKey);
                    this.redisTemplate.opsForSet().add(roomKey, players.toArray());
                    return true;
                } else {
                    return false;
                }
            }
        } catch (Exception e) {
            log.error("更新玩家位置时出现异常: {}", e.getMessage(), e);
            return false;
        }
    }

    private String findAvailableRoom(MBTISquare mbtiSquare) {
        try {
            Set<String> keys = this.redisTemplate.keys("game:room:*");
            String targetRoomId = null;
            int maxPlayers = 0;
            if (keys != null) {
                for(String key : keys) {
                    String roomId = key.substring("game:room:".length());
                    if (!"counter".equals(roomId)) {
                        RoomInfo roomInfo = this.getRoomInfo(roomId);
                        if (roomInfo != null && mbtiSquare.equals(roomInfo.getMbtiSquare())) {
                            int playerCount = this.getRoomPlayerCount(roomId);
                            if (playerCount < 2 && playerCount > maxPlayers) {
                                maxPlayers = playerCount;
                                targetRoomId = roomId;
                            }
                        }
                    }
                }
            }

            return targetRoomId;
        } catch (Exception e) {
            log.error("寻找可用房间时出现异常: {}", e.getMessage(), e);
            return null;
        }
    }

    private String createNewRoom(MBTISquare mbtiSquare) {
        try {
            if (!Boolean.TRUE.equals(this.redisTemplate.hasKey("game:room:counter"))) {
                this.redisTemplate.opsForValue().set("game:room:counter", 0L);
            }

            Long roomNumber = this.redisTemplate.opsForValue().increment("game:room:counter");
            String var7 = mbtiSquare.name();
            String roomId = var7 + "_Room_" + roomNumber;
            String roomKey = "game:room:" + roomId;
            String roomMbtiKey = "game:room:" + roomId + ":mbti";
            this.redisTemplate.opsForValue().set(roomMbtiKey, mbtiSquare.name(), 30L, TimeUnit.MINUTES);
            this.redisTemplate.expire(roomKey, 30L, TimeUnit.MINUTES);
            return roomId;
        } catch (Exception e) {
            log.error("创建新房间时出现异常: {}", e.getMessage(), e);
            String var10000 = mbtiSquare.name();
            return var10000 + "_Room_" + System.currentTimeMillis();
        }
    }

    private Position generateRandomFreePosition(String roomId) {
        try {
            String roomKey = "game:room:" + roomId;
            Set<Object> players = this.redisTemplate.opsForSet().members(roomKey);
            Set<String> occupied = new HashSet();
            if (players != null) {
                for(Object obj : players) {
                    if (obj instanceof Player) {
                        Player p = (Player)obj;
                        if (p.getPosition() != null) {
                            int var10001 = p.getPosition().getX();
                            occupied.add(var10001 + "," + p.getPosition().getY());
                        }
                    }
                }
            }

            Random random = new Random();

            for(int attempt = 0; attempt < 100; ++attempt) {
                int x = random.nextInt(10);
                int y = random.nextInt(10);
                String key = x + "," + y;
                if (!occupied.contains(key)) {
                    return new Position(x, y);
                }
            }

            return new Position(0, 0);
        } catch (Exception e) {
            log.warn("生成随机位置失败，使用默认(0,0): {}", e.getMessage());
            return new Position(0, 0);
        }
    }

    public int getActiveConnections() {
        try {
            Set<String> keys = this.redisTemplate.keys("game:room:*");
            if (keys == null) {
                return 0;
            } else {
                int totalConnections = 0;

                for(String key : keys) {
                    if (!key.equals("game:room:counter")) {
                        Long size = this.redisTemplate.opsForSet().size(key);
                        if (size != null) {
                            totalConnections += size.intValue();
                        }
                    }
                }

                return totalConnections;
            }
        } catch (Exception e) {
            log.error("获取活跃连接数时出现异常: {}", e.getMessage(), e);
            return 0;
        }
    }

    public int getTotalPlayers() {
        try {
            Set<String> keys = this.redisTemplate.keys("game:room:*");
            if (keys == null) {
                return 0;
            } else {
                int totalPlayers = 0;

                for(String key : keys) {
                    if (!key.equals("game:room:counter") && !key.contains(":mbti")) {
                        Long size = this.redisTemplate.opsForSet().size(key);
                        if (size != null) {
                            totalPlayers += size.intValue();
                        }
                    }
                }

                return totalPlayers;
            }
        } catch (Exception e) {
            log.error("获取总玩家数时出现异常: {}", e.getMessage(), e);
            return 0;
        }
    }

    public List<RoomInfo> getRoomsByMBTISquare(MBTISquare mbtiSquare) {
        try {
            List<RoomInfo> roomInfos = new ArrayList();

            for(RoomInfo room : this.getAllRooms()) {
                if (mbtiSquare.equals(room.getMbtiSquare())) {
                    roomInfos.add(room);
                }
            }

            return roomInfos;
        } catch (Exception e) {
            log.error("根据MBTI广场获取房间时出现异常: {}", e.getMessage(), e);
            return new ArrayList();
        }
    }

    public Map<MBTISquare, Integer> getMBTISquareStats() {
        try {
            Map<MBTISquare, Integer> stats = new HashMap();

            for(MBTISquare mbtiType : MBTISquare.values()) {
                stats.put(mbtiType, 0);
            }

            for(RoomInfo room : this.getAllRooms()) {
                if (room.getMbtiSquare() != null) {
                    stats.put(room.getMbtiSquare(), (Integer)stats.getOrDefault(room.getMbtiSquare(), 0) + 1);
                }
            }

            return stats;
        } catch (Exception e) {
            log.error("获取MBTI广场统计时出现异常: {}", e.getMessage(), e);
            return new HashMap();
        }
    }
}
